#!/usr/bin/env python
# -*- coding: UTF-8 -*-
'''
@Project ：V2 
@File    ：tabu_ablation_experiment.py
@IDE     ：PyCharm 
@Author  ：郭星
@Date    ：2025/10/18 0:02 
'''
#!/usr/bin/env python
# -*- coding: UTF-8 -*-
'''
改进禁忌搜索的消融实验（含五种策略的组合测试）
'''

import os
import json
import matplotlib.pyplot as plt
import time
from typing import List, Dict
from algorithm_comparison import (
    GasSchedulingInstanceGenerator,
    BaseSchedulingAlgorithm,
    ImprovedTabuSearch
)

# 设置中文显示
plt.rcParams["font.family"] = ["SimHei", "WenQuanYi Micro Hei", "Heiti TC"]
plt.rcParams["axes.unicode_minus"] = False


def select_instance():
    """选择算例"""
    print("===== 算例选择 =====")
    instance_files = GasSchedulingInstanceGenerator.list_instances()

    if not instance_files:
        print("未找到算例，请先生成算例！")
        exit(1)

    for i, file_path in enumerate(instance_files, 1):
        try:
            with open(file_path, 'r') as f:
                data = json.load(f)
                wp = data['parameters'].get('num_workpieces', '未知')
                comp = data['parameters'].get('num_components', '未知')
                print(f"{i}. {file_path} (工件数: {wp}, 组分数: {comp})")
        except:
            print(f"{i}. {file_path} (格式可能不正确)")

    while True:
        try:
            choice = int(input(f"请选择算例 (1-{len(instance_files)}): ")) - 1
            if 0 <= choice < len(instance_files):
                selected_file = instance_files[choice]
                print(f"已选择算例: {selected_file}")
                return GasSchedulingInstanceGenerator.load_instance(selected_file)
        except ValueError:
            print("请输入有效数字")


def run_tabu_ablation():
    """运行禁忌搜索消融实验（测试五种策略的组合）"""
    # 选择算例
    instance = select_instance()

    # 定义五种策略的组合（共5种消融方案）
    strategies = [
        # 全策略（对照基准）
        {
            "name": "全策略",
            "use_elite": True,
            "dynamic_tabu": True,
            "diverse": True,
            "history": True,
            "优劣种群分离": True
        },
        # 消融1：无精英保护
        {
            "name": "无精英保护",
            "use_elite": False,
            "dynamic_tabu": True,
            "diverse": True,
            "history": True,
            "优劣种群分离": True
        },
        # 消融2：固定禁忌长度
        {
            "name": "固定禁忌长度",
            "use_elite": True,
            "dynamic_tabu": False,
            "diverse": True,
            "history": True,
            "优劣种群分离": True
        },
        # 消融3：无多样化扰动
        {
            "name": "无多样化扰动",
            "use_elite": True,
            "dynamic_tabu": True,
            "diverse": False,
            "history": True,
            "优劣种群分离": True
        },
        # 消融4：无历史启发
        {
            "name": "无历史启发",
            "use_elite": True,
            "dynamic_tabu": True,
            "diverse": True,
            "history": False,
            "优劣种群分离": True
        },
        # 消融5：无优劣种群分离
        {
            "name": "无优劣种群分离",
            "use_elite": True,
            "dynamic_tabu": True,
            "diverse": True,
            "history": True,
            "优劣种群分离": False
        }
    ]

    # 运行所有策略组合
    algorithms = []
    for strategy in strategies:
        ts = ImprovedTabuSearch(
            instance=instance,
            population_size=50,
            tabu_size=15,
            neighborhood_size=8,
            max_iter=100,
            use_elite_protection=strategy["use_elite"],
            dynamic_tabu_length=strategy["dynamic_tabu"],
            diverse_perturbation=strategy["diverse"],
            history_heuristic=strategy["history"],
            优劣种群分离=strategy["优劣种群分离"],
            name=strategy["name"]
        )
        algorithms.append(ts)
        print(f"\n===== 运行 {ts.name} =====")
        ts.optimize()
        print(f"{ts.name} 最优时间: {ts.best_time:.2f}")
        # 绘制甘特图（可选）
        ts.plot_gantt_chart(title_suffix=f"(最优时间: {ts.best_time:.2f})")

    # 绘制收敛曲线对比
    plt.figure(figsize=(12, 8))
    colors = ['blue', 'green', 'red', 'purple', 'orange', 'brown']
    linestyles = ['-', '--', '-.', ':', '-', '--']
    for i, algo in enumerate(algorithms):
        plt.plot(
            range(len(algo.iteration_best_times)),
            algo.iteration_best_times,
            color=colors[i],
            linestyle=linestyles[i],
            linewidth=2,
            label=algo.name
        )
    plt.xlabel("迭代次数")
    plt.ylabel("最优完成时间")
    plt.title("改进禁忌搜索的消融实验：不同策略组合的收敛曲线")
    plt.legend()
    plt.grid(True, linestyle='--')
    plt.tight_layout()
    plt.show()

    # 输出实验结果汇总
    print("\n===== 消融实验结果汇总 =====")
    for algo in algorithms:
        print(f"{algo.name}: 最优完成时间 = {algo.best_time:.2f}")


if __name__ == "__main__":
    run_tabu_ablation()